#include <iostream>
#include <memory>
#include <algorithm>

using std::cout;
using std::endl;
using std::copy;
using std::uninitialized_copy;

template<typename T>
class Vector
{
public:
    /* typedef T * iterator;//C++98 */
    using iterator =  T *;

    iterator begin()
    {
        return _start;
    }

    iterator end()
    {
        return _finish;
    }

    Vector()
    : _start(nullptr)
    , _finish(nullptr)
    , _end_of_storage(nullptr)
    {

    }

    ~Vector();

    void push_back(const T &value); 
    void pop_back();    

    int size() const;
    int capacity() const;
private:
    void reallocate();//重新分配内存,动态扩容要用的
private:    
    static std::allocator<T> _alloc;//静态数据成员

    T * _start;            //指向数组中的第一个元素
    T * _finish;           //指向最后一个实际元素之后的那个元素
    T * _end_of_storage;   //指向数组本身之后的位置
};

//静态数据成员在类的外面进行初始化（不能在构造函数的
//初始化列表中进行）
template <typename T>
std::allocator<T> Vector<T>::_alloc;//静态数据成员

template <typename T>
Vector<T>::~Vector()
{
    //先将对象销毁然后再将空间回收
    if(_start)
    {
        while(_start != _finish)
        {
            _alloc.destroy(--_finish);//ok,销毁对象
        }
        _alloc.deallocate(_start, capacity());//释放空间
    }
}

template <typename T>
void Vector<T>::push_back(const T &value)
{
    //在尾部插入一个元素
    if(size() == capacity())
    {
        //需要进行扩容
        reallocate();
    }

    if(size() < capacity())
    {
        _alloc.construct(_finish++, value);
    }

}

template <typename T>
void Vector<T>::pop_back()
{
    if(size() > 0)
    {
        //销毁对象
        _alloc.destroy(--_finish);
    }
}

template <typename T>
int Vector<T>::size() const
{
    return _finish - _start;
}

template <typename T>
int Vector<T>::capacity() const
{
    return _end_of_storage - _start;
}

template <typename T>
void Vector<T>::reallocate()//重新分配内存,动态扩容要用的
{
    //1、首先申请新的空间(新的空间是老的空间的2倍)
    int oldCapacity = size();
    int newCapacity = 2 * oldCapacity > 0 ? 2 * oldCapacity : 1;

    T *ptmp = _alloc.allocate(newCapacity);//申请新的空间
    if(_start)
    {
        //2、将老的空间上的元素（对象）拷贝到新的空间来
        uninitialized_copy(_start, _finish, ptmp);
        
        //3、将老的空间上的元素（对象）回收并且将空间进行释放
        while(_start != _finish)
        {
            /* _alloc.destroy(_start++);//ok */
            _alloc.destroy(--_finish);//ok,销毁老的空间上的对象
        }
        _alloc.deallocate(_start, oldCapacity);//释放老的空间
    }
    
    //4、将三个指针与新的空间产生关系
    _start = ptmp;
    _finish = _start + oldCapacity;
    _end_of_storage = _start + newCapacity;
}

void display(const Vector<int> &con)
{
    cout << "con.size() = " << con.size() << endl;
    cout << "con.capacity() = " << con.capacity() << endl;
}

void test()
{
    Vector<int> vec;
    display(vec);

    cout << endl;
    vec.push_back(1);
    display(vec);

    cout << endl;
    vec.push_back(2);
    display(vec);

    cout << endl;
    vec.push_back(3);
    display(vec);

    cout << endl;
    vec.push_back(4);
    display(vec);

    cout << endl;
    vec.push_back(5);
    display(vec);

    cout << endl;
    vec.push_back(6);
    display(vec);

    cout << endl;
    vec.push_back(7);
    display(vec);

    cout << endl;
    vec.push_back(8);
    display(vec);

    cout << endl;
    vec.push_back(4);
    display(vec);

    //遍历
    for(auto &elem : vec)
    {
        cout << elem << "  ";
    }
    cout <<endl;
}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

